package com.windward.vii.utils;

import com.alibaba.fastjson.JSONObject;
import com.windward.vii.domain.user.UserAgent;
import com.windward.vii.utils.encrypt.Digests;
import com.windward.vii.utils.encrypt.MD5Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.DigestUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.UUID;
import java.util.regex.Pattern;

/**
 * 工具类
 */
public class Utils {

    private static Logger logger = LoggerFactory.getLogger(Utils.class);

    public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 得到显示时间
     * @return   yyyy-MM-dd HH:mm:ss
     */
    public static String dateToString(Date date) {
        if (date == null) {
            return null;
        }
        return sdf.format(date);
    }

    /**
     * 根据显示时间得到日期
     * @param time  yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static Date stringToDate(String time) {
        if (StringUtils.isBlank(time)) {
            return null;
        }
        try {
            return sdf.parse(time);
        } catch (ParseException e) {
            e.printStackTrace();
            return new Date();
        }
    }


    /**
     * 将对象转成json串
     * @param obj
     * @return
     */
    public static String toJson(Object obj) {
        if (obj == null)
            return null;
        JSONObject result = new JSONObject();
        Field[] fields = obj.getClass().getDeclaredFields();
        for (int j = 0; j < fields.length; j++) {
            fields[j].setAccessible(true);
            // 字段名
            String key = fields[j].getName();
            // 字段类型
            String type = fields[j].getType().getName();
            try {
                // 字段值
                Object value = fields[j].get(obj);
                if (value != null) {
                    //如果是Date类型，转换成 yyyy-MM-dd HH:mm:ss
                    if (type.equalsIgnoreCase("java.util.Date")) {
                        value = Utils.dateToString((Date) value);
                    }
                    result.put(key, value.toString());
                } else {
                    //如果是Integer类型，转换成0
                    if (type.equalsIgnoreCase("java.lang.Integer") || type.equalsIgnoreCase("java.lang.Long")) {
                        value = 0;
                        result.put(key, value.toString());
                    }
                }
            } catch (Exception e) {
                System.out.println("object field transfer failed, but it`s ok. field = " + key + ", type = " + type);
            }
        }
        return JSONObject.toJSONString(result);
    }

    /**
     * 将json串转成对象
     * @param json
     * @param clazz
     * @return
     */
    public static Object fromJson(String json, Class clazz) {
        if (StringUtils.isNotEmpty(json)) {
            return JSONObject.parseObject(json, clazz);
        }
        return null;
    }

    /**
     * 将newObj中待更新的字段值，填充到oldObj中做替换
     * @param oldObj
     * @param newObj
     * @return  更新后的obj
     */
    public static Object fillObj(Object oldObj, Object newObj) {
        Field[] oldf = oldObj.getClass().getDeclaredFields();
        Field[] newf = newObj.getClass().getDeclaredFields();
        for (int j = 0; j < oldf.length; j++) {
            try {
                newf[j].setAccessible(true);
                if (newf[j].get(newObj) != null) {
                    oldf[j].setAccessible(true);
                    oldf[j].set(oldObj, newf[j].get(newObj));
                }
            } catch (IllegalAccessException e) {
                System.out.println("object field transfer failed, but it`s ok. field = " + newf[j].getName() + ", type = " + newf[j].getType().getName());
            }
        }
        return oldObj;
    }


    /**
     * 生成随机盐
     * @return
     */
    public static String generateSalt() {
        return Encodes.encodeHex(Digests.generateSalt(4));
    }

    /**
     * 密码加密
     * @param salt
     * @param password
     * @return
     */
    public static String encryptPassword(String salt, String password) {
        return MD5Util.sha256Hex(salt, password);
    }

    public static void main(String[] args) {
        String salt = generateSalt();
        String password = encryptPassword(salt, "111111");

        System.out.println("salt="+salt);
        System.out.println("password="+password);
    }

    public static String genToken() {
        try {
            return DigestUtils.md5DigestAsHex(UUID.randomUUID().toString().getBytes("UTF-8")).toUpperCase();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static final String ZS_TOKEN_PRE = "ZS-";
    public static final String LS_TOKEN_PRE = "LS-";
    public static final String LS_TOKEN = "L";
    public static final String DL_TOKEN = "X";

    public static String genZSToken() {
        String token = genToken();
        if(token != null) {
            return ZS_TOKEN_PRE + token;
        }
        return token;
    }

    public static String genLSToken() {
        String token = genToken();
        if(token != null) {
            return LS_TOKEN_PRE + token;
        }
        return token;
    }

    /**
     * 获得 token true 登陆 token, false 未登陆 token
     * */
    public static String getToken(Boolean b) {

        String token = genToken();
        if(b) {

            return DL_TOKEN+token;

        } else {

            return LS_TOKEN+token;

        }
    }

    /**
     * 验证手机号码，11位数字
     * @param mobile
     * @return
     */
    public static boolean checkMobile(String mobile) {
        if (mobile == null) {
            return false;
        }
        String regex = "\\d{11}";
        return Pattern.matches(regex, mobile);
    }

    /**
     * 检查ip
     * @param ip
     * @return
     */
    public static boolean checkIp(String ip) {
        if (ip == null) {
            return false;
        }
        String regex = "^((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]|[*])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]|[*])$";
        return ip.matches(regex);
    }


    public static String getRemoteHost(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        String[] arr = ip.split(",");
        ip = arr[0];
        return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
    }

    /**
     * 验证密码
     * @param password
     * @return
     */
    public static boolean checkPassword(String password) {
        if (password == null) {
            return false;
        }
//        String regex = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,16}$";//数字、字母组合
        String regex = "^[0-9A-Za-z~!@#$%^&*()_+:\"|<>?`=;',./-]{6,18}$";//字母、数字、特殊字符
        return password.matches(regex);
    }

    public static boolean isNumeric(String str){
        Pattern pattern = Pattern.compile("[0-9]*");
        return pattern.matcher(str).matches();
    }

    public static boolean isValidDate(String str) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        try {
            format.setLenient(false);
            format.parse(str);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 得到一个字符串的长度,显示的长度,一个汉字或日韩文长度为2,英文字符长度为1
     * @param str 需要得到长度的字符串
     * @return int 得到的字符串长度
     */
    public static int length(String str) {
        if (str == null)
            return 0;
        char[] c = str.toCharArray();
        int len = 0;
        for (int i = 0; i < c.length; i++) {
            len++;
            if (!isLetter(c[i])) {
                len++;
            }
        }
        return len;
    }

    public static boolean isLetter(char c) {
        int k = 0x80;
        return c / k == 0 ? true : false;
    }

    public static int getRandom(int min, int max){
        Random random = new Random();
        return random.nextInt(max) % (max - min + 1) + min;
    }


    /**
     * iOS：User-Agent:Yema/1.0.1 (iPhone; iOS 11.0.3; Scale/2.00)
     * @param httpUserAgent
     * @return
     */

    public static UserAgent wrapUserAgent(String httpUserAgent) {
        if(StringUtils.isBlank(httpUserAgent)) {
            return null;
        }

        // Yema/1.0.1 (iPhone; iOS 11.0.3; Scale/2.00)
        UserAgent userAgent = new UserAgent();
        String[] arr = httpUserAgent.split(" ");
        if(httpUserAgent.contains("iOS")) {
            userAgent.setOsType("iOS");
        } else if(httpUserAgent.contains("Android")) {
            userAgent.setOsType("Android");
        } else {
            userAgent.setOsType("unknown");
        }

        // Yema/1.0.1
        String first = arr[0];
        if(first != null) {
            String[] firstArr = first.split("/");
            if(firstArr.length > 1) {
                userAgent.setAppVer(firstArr[1]);
            }
        }

        // (iPhone; iOS 11.0.3; Scale/2.00)
        if(arr.length > 1) {
            String second = arr[1];
            second = second.replace("(", "");
            second = second.replace(")", "");
            String[] secondArr = second.split("; ");
            if(secondArr.length > 0) {
                userAgent.setModel(secondArr[0]); // iPhone
                if(secondArr.length > 1) {
                    String osStr = secondArr[1]; // iOS 11.0.3;
                    String[] osStrArr = osStr.split(" ");
                    if(osStrArr.length > 1) {
                        userAgent.setSysVer(osStrArr[1]);
                    }
                }
            }
        }

        return userAgent;
    }

    // Yema/1.0.1 (iPhone; iOS 11.0.3; Scale/2.00)
//    public static String getAppVersionFromUserAgent(String httpUserAgent) {
//        String appVersion = "";
//        if(!StringUtils.isBlank(httpUserAgent)) {
//            String[] arr = httpUserAgent.split(" ");
//            String first = arr[0];
//            if(first != null) {
//                String[] firstArr = first.split("/");
//                if(firstArr.length > 1) {
//                    appVersion = firstArr[1];
//                }
//            }
//        }
//        logger.info("getAppVersionFromUserAgent={}", appVersion);
//        return appVersion;
//    }

}
